'use strict'
const { Op } = require('sequelize')
const BaseController = require('./baseController')
class MenuController extends BaseController {
	constructor(...args) {
		super(...args)
		this.serviceName = 'menuS'
		this.uniqueWords = ['menu_name', 'perms', 'path']
		this.validateUpdatePath = 'menu.updatedMenu'
		this.validateUpdateBTnPath = 'menu.updatedBtn'
		this.validateUpdateSubMenuPath = 'menu.updatedSbuMenu'
		this.validateCreatedPath = 'menu.createdMenu'
		this.validateCreatedSubMenuPath = 'menu.createdSubMenu'
		this.validateCreatedBtnPath = 'menu.createdBtn'
	}
	/**
	 * 完整的菜单树
	 * @returns
	 */
	async treeMenu() {
		const { service, helper } = this.ctx
		const res = await service.menuS.list({
			// where: {
			// 	visible: {
			// 		[Op.ne]: 0,
			// 	},
			// },
		})
		if (res) {
			const data = helper.transformToTree(res)
			// 为了前端数格式据统一处理
			return this.success({ data: { ['count']: data.length, ['rows']: data } })
		}
	}
	/**
	 * 根据角色返回 菜单树
	 * @returns
	 */
	async treeMenuByRoleIds() {
		const { service, helper } = this.ctx
		const { ids } = this.ctx.request.body
		if (!ids) {
			this.fail({ message: '角色ids不能为空' })
			return
		}
		let data = await service.menuS.treeMenuByRoleIds(ids)

		let res = []
		data.forEach((item) => {
			if (item && item.dataValues && item.dataValues.t_menu) {
				res.push(item.dataValues.t_menu)
			}
		})

		if (res) {
			const data = helper.transformToTree(res)
			// return this.success({ data })
			// 保持数据格式的一致性
			return this.success({ data: { ['count']: data.length, ['rows']: data } })
		}
	}

	/**
	 *  菜单新建
	 * PUT修改 /posts/:id
	 */

	async create() {
		const { service, helper } = this.ctx
		let bodyObj = this.ctx.request.body
		// 验证规则 默认是创建菜单的验证规则
		if (bodyObj.menu_type === undefined || bodyObj.menu_type === null) {
			this.fail({ message: '菜单的类型不能为空' })
		}
		if (bodyObj.menu_type > 2) {
			this.fail({ message: '暂不支持此类型的菜单创建' })
			return
		}
		let { bodyObjs, validatePath } = this.separateType(
			bodyObj,
			this.validateCreatedBtnPath,
			this.validateCreatedSubMenuPath,
			this.validateCreatedPath
		)
		if (validatePath) {
			const validateResult = await helper.validateResult(validatePath, {
				...bodyObjs,
			})
			if (!validateResult) return
		}
		const uniqueWords = this.uniqueWords ? this.uniqueWords : null
		const { flag, message } = await service[this.serviceName].create(
			bodyObjs,
			uniqueWords
		)
		if (flag) {
			this.success({ message })
		} else {
			this.fail({ message })
		}
	}

	/**
	 * 菜单更新
	 * @returns
	 */
	async update() {
		const { service, helper } = this.ctx
		let { id } = this.ctx.params
		let bodyObj = this.ctx.request.body
		if (bodyObj.menu_type === undefined || bodyObj.menu_type === null) {
			this.fail({ message: '菜单的类型不能为空' })
		}
		if (bodyObj.menu_type > 2) {
			this.fail({ message: '暂不支持此类型的菜单创建' })
			return
		}
		let { bodyObjs, validatePath } = this.separateType(
			{ ...bodyObj, id },
			this.validateUpdatePath,
			this.validateUpdateSubMenuPath,
			this.validateUpdateBTnPath
		)

		if (validatePath) {
			const validateResult = await helper.validateResult(validatePath, {
				...bodyObjs,
			})
			if (!validateResult) return
		}
		const uniqueWords = this.uniqueWords ? this.uniqueWords : null
		const { flag, message } = await service[this.serviceName].update(
			id,
			{ ...bodyObjs, ['id']: id },
			uniqueWords
		)
		if (flag) {
			this.success({ message })
		} else {
			this.fail({ message })
		}
	}

	/**
	 * 分类
	 * 公共函数
	 */

	separateType(bodyObjs, menu, subMenu, menuBnt) {
		const menu_type = bodyObjs?.menu_type
		let validatePath = null
		//不用类型的菜单过滤字段不同
		let filters = []
		if (menu_type == 2) {
			// 按钮创建规则匹配
			validatePath = menu
			filters = ['path', 'icon', 'is_cache', 'component']
		} else if (menu_type == 1) {
			// 子菜单创建创建规则匹配
			validatePath = subMenu
			filters = ['icon', 'perms']
		} else if (menu_type == 0) {
			// 创建菜单规则匹配
			validatePath = menuBnt
			filters = ['path', 'perms', 'is_cache', 'component']
		}
		bodyObjs = this.filterProperty(filters, bodyObjs)
		return {
			bodyObjs,
			validatePath,
		}
	}
	/**
	 * 工具函数 过滤不要的字段
	 * @param {*} properties
	 * @param {*} obj
	 * @returns
	 */
	filterProperty(properties, obj) {
		Object.keys(obj).forEach((key) => {
			if (properties.includes(key)) {
				delete obj[key]
			}
		})
		return obj
	}
}

module.exports = MenuController
